package org.kernely.stream.userpage;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Set;

import org.kernely.security.dao.UserDetailsDAO;
import org.kernely.security.persistence.Role;
import org.kernely.security.persistence.User;
import org.kernely.security.persistence.UserDetails;
import org.kernely.stream.StreamBundle;
import org.kernely.stream.dao.MessageDAO;
import org.kernely.stream.persistence.Message;
import org.kernely.stream.utils.FavButton;
import org.kernely.ui.mvp.KernelyPresenter;
import org.kernely.ui.utils.DisplayProfileEvent;
import org.kernely.ui.utils.KernelyDialogWindow;
import org.kernely.ui.utils.KernelyNotification;

import com.vaadin.terminal.FileResource;
import com.vaadin.terminal.Sizeable;
import com.vaadin.terminal.ThemeResource;
import com.vaadin.ui.Button;
import com.vaadin.ui.Embedded;
import com.vaadin.ui.Label;
import com.vaadin.ui.Table;
import com.vaadin.ui.Window;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.themes.Reindeer;

/**
 *	This presenter fill its view with all the favorites of a user.
 */
public class StreamFavoritesPresenter extends KernelyPresenter<StreamFavoritesView> {
	/**
	 * Bind method, to do some stuff on the view.
	 */
	@Override
	public void bind() {
		// Set the style of the table
		view.getFavoritesTable().setCellStyleGenerator(new Table.CellStyleGenerator() {
			/**
			 * @see com.vaadin.ui.Table.CellStyleGenerator#getStyle(java.lang.Object, java.lang.Object)
			 */
			public String getStyle(Object itemId, Object propertyId) {
				Message message = MessageDAO.getInstance().findMessageById((Integer)itemId);
				if(message.getComments() != null && message.getComments().size() > 0){
					if(MessageDAO.getInstance().getFavorites(StreamBundle.getSecurityService().getCurrentUser()).contains(message)){
						return "favcomments";
					}
					else{
						return "comments";
					}
				}
				else{
					if(MessageDAO.getInstance().getFavorites(StreamBundle.getSecurityService().getCurrentUser()).contains(message)){
						return "favorites";
					}
					else{
						return "messages";
					}
				}
			}
		});
		
		// Display favorites in table
		listFavorites();
	}
	
	/**
	 * Load all the favorites and display them.
	 */
	public void listFavorites(){
		view.getFavoritesTable().removeAllItems();
		User current = StreamBundle.getSecurityService().getCurrentUser();
		Set<Message> favorites = MessageDAO.getInstance().getFavorites(current);
		
		for (Message message : favorites){
				addFavoriteIntoTable(message);
		}
	}

	
	// Add a message into the table
	private final void addFavoriteIntoTable(final Message message){
		// Writer infos
		final UserDetails details = UserDetailsDAO.getInstance().getUserDetails(message.getUser());

		//Date
		SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");

		String user = null;
		if (details != null){
			user = details.getFirstname() + " " + details.getName() + " (" + details.getUser().getLogin() + ")";
		} else {
			user = "System";
		}

		Date messageDate = message.getDate();
		Calendar date1 = new GregorianCalendar();
		date1.setTime(messageDate);
		Calendar date2 = new GregorianCalendar();
		long date1long = date1.getTimeInMillis();
		long date2long = date2.getTimeInMillis();

		// Difference between the two dates
		long timebetweend1d2 = date2long - date1long;
		String dateToDisplay = "";
		// less than one minute
		if(timebetweend1d2 < 60000){
			dateToDisplay = "a few seconds ago";
		}
		else{
			// less than one hour
			if(timebetweend1d2 < 3600000){
				long nbMin = timebetweend1d2 / 1000 / 60;
				dateToDisplay = nbMin + " minutes ago";
			}
			else{
				// less than one day
				if(timebetweend1d2 < 86400000){
					long nbHour = timebetweend1d2 / 1000 / 60 / 60;
					dateToDisplay = nbHour + " hours ago";
				}
				else{
					// less than one week
					if(timebetweend1d2 < 604800000){
						long nbDays = timebetweend1d2 / 1000 / 60 / 60 / 24;
						dateToDisplay = nbDays + " days ago";
					}
					else{
						dateToDisplay = dateFormat.format(messageDate);
					}
				}
			}
		}

		// Format the text to be displayed in the table
		Label messageContent;
		messageContent = new Label(
				"<span style=\"font-weight:bold;\">"+message.getStream().getTitle()+"</span><br/>"
				+ message.getContentCache()+"<br/>"
				+"<span style=\"font-style:italic;color:grey\">From "+user + ", " + dateToDisplay + ".</span>",Label.CONTENT_XHTML);

		// Set the image
		Embedded imageEmbedded = new Embedded();
		// The image for "system" user is a default image
		if (details == null){
			ThemeResource imageResource = new ThemeResource("img/default_bundle.png");
			imageEmbedded.setSource(imageResource);
		}
		else {
			if (details.getImage() == null || details.getImage().equals("")){
				// Default images are located in src/main/resources/VAADIN/themes/kernelytheme/img
				if (details.getCivility() == 0){
					ThemeResource imageResource = new ThemeResource("img/default_male.png");
					imageEmbedded.setSource(imageResource);
				}
				else {
					ThemeResource imageResource = new ThemeResource("img/default_female.png");
					imageEmbedded.setSource(imageResource);
				}
			} else {
				File imageFile = new File("/tmp/uploads/"+details.getImage());
				if (imageFile != null){
					// We set the image only if the application is available
					if (view.getApplication() != null){
						FileResource imageResource = new FileResource(imageFile, view.getApplication());
						imageEmbedded.setSource(imageResource);	        	
					}
				}
			}        
		}
		imageEmbedded.setHeight(48, Sizeable.UNITS_PIXELS);
		imageEmbedded.setWidth(48, Sizeable.UNITS_PIXELS);

		// Delete button, only for users which correct rights
		Button deleteButton = null;
		if (StreamBundle.getSecurityService().currentUserHasOneOf(Role.ROLE_ADMINISTRATOR)
				|| StreamBundle.getSecurityService().currentUserHasPermission(
						message.getStream().getCategory() + ":deletemessages:" + message.getStream().getUid())
						|| message.getUser().equals(StreamBundle.getSecurityService().getCurrentUser())){
			deleteButton = new Button();
			deleteButton.setIcon(new ThemeResource("img/cancel_icon16*16.png"));
			deleteButton.setStyleName(Reindeer.BUTTON_LINK);

			deleteButton.setSizeUndefined();
			deleteButton.addListener(new Button.ClickListener() {
				/**
				 * @see com.vaadin.ui.Button.ClickListener#buttonClick(com.vaadin.ui.Button.ClickEvent)
				 */
				public void buttonClick(ClickEvent event) {
					deleteProcess(message);
				}
			});
		}	

		// creation of profile button
		Button buttonProfile = null;
		if (! user.equals("System")){
			// Display the profile only if the user is not the System
			buttonProfile = new Button();
			buttonProfile.setIcon(new ThemeResource("img/profile.png"));
			buttonProfile.setStyleName(Reindeer.BUTTON_LINK);
			buttonProfile.addListener(new Button.ClickListener() {
				/**
				 * @see com.vaadin.ui.Button.ClickListener#buttonClick(com.vaadin.ui.Button.ClickEvent)
				 */
				public void buttonClick(ClickEvent event) {
					displayProfile(details);
				}
			});
		}

		// Create the message
		this.view.getFavoritesTable().addItem(new Object[] {
				imageEmbedded,
				messageContent,
				buttonProfile,
				new FavButton(message),
				deleteButton,
				message.getDate()}, message.getId());
	}
	
	/**
	 * Display the profile selected
	 * @param details : the profile to display
	 */
	private void displayProfile(UserDetails details){
		StreamBundle.getEventBus().broadcastEvent(new DisplayProfileEvent(this, details));	
	}

	/**
	 * Process to delete a message, with confirm dialog and notification.
	 */
	private void deleteProcess(final Message message){
		boolean isAdmin = StreamBundle.getSecurityService().currentUserHasOneOf(Role.ROLE_ADMINISTRATOR);
		String permission = "Streams/Users:deletemessages:"+message.getStream().getUid();
		boolean canDelete = StreamBundle.getSecurityService().currentUserHasPermission(permission);

		final Window window = view.getWindow();

		// Delete the message if the user have rights.
		if (isAdmin || canDelete){

			// Confirm window
			final KernelyDialogWindow confirm = new KernelyDialogWindow(
					"Kernely - Delete message", "Do you really want to delete this message ?",
					KernelyDialogWindow.ASKING_ICON);
			confirm.setConfirmButtonCaption("Yes");
			confirm.setCancelButtonCaption("No");

			// Adding listeners on window's "confirm" buttons click
			confirm.getConfirmButton().addListener(new Button.ClickListener() {
				/**
				 * The action when the "Yes" button is clicked
				 */
				public void buttonClick(ClickEvent event) {
					MessageDAO mdao = MessageDAO.getInstance();

					// Disable the user in the database
					mdao.deleteMessage(message);
					window.removeWindow(confirm);

					// Remove the confirm window
					window.showNotification(new KernelyNotification("Message deleted.", KernelyNotification.INFO_ICON));

					view.getFavoritesTable().removeItem(message.getId());
				}
			});

			window.addWindow(confirm);
		}
	}
	
	
	
}
